package cae.gui.chat;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.StyledDocument;

import org.jvnet.flamingo.common.CommandButtonDisplayState;
import org.jvnet.flamingo.common.JCommandButton;
import org.jvnet.flamingo.common.JCommandButtonPanel;
import org.jvnet.flamingo.common.RichTooltip;
import org.jvnet.flamingo.common.icon.ImageWrapperResizableIcon;
import org.jvnet.flamingo.common.popup.JCommandPopupMenu;
import org.jvnet.flamingo.common.popup.JPopupPanel;
import org.jvnet.flamingo.common.popup.PopupPanelCallback;

import cae.gui.util.CaeImage;
import cae.gui.util.CaeJFrame;
import cae.logic.chat.CaeChatManager;
import cae.logic.chat.CaeChatMessage;
import cae.logic.destination.CaeDestination;
import cae.logic.destination.CaeDestinatiosManager;
import cae.logic.emo.CaeEmoticonDefinition;
import cae.logic.emo.CaeEmoticonsManager;

public class CaeChatDialog extends CaeJFrame implements ActionListener, Observer
{
	private static final long serialVersionUID = 1L;
	private JPanel panel = null;

	private StyledDocument doc;
	private final JTextField inputText = new JTextField();
	private final CaeChatManager logic;
	//private static Logger logger = Logger.getLogger(CaeChatDialog.class);
	private final TrayIcon iconTray;
	private CaeChatDialog dialog;
	private JTextPane textPane;

	public CaeChatDialog(JFrame frame, CaeChatManager logicp, TrayIcon iconTrayP)
	{
		super("Chat");

		dialog = this;
		setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
		this.logic = logicp;
		this.iconTray = iconTrayP;

		addWindowListener(new WindowListener()
		{
			public void windowActivated(WindowEvent arg0) {
				CaeImage.setIcon(iconTray, CaeImage.DEFAULT);
			}
			public void windowClosed(WindowEvent arg0) {}
			public void windowClosing(WindowEvent arg0) {
				dialog.logic.deleteObserver(dialog);
				dispose();
			}
			public void windowDeactivated(WindowEvent arg0) {}
			public void windowDeiconified(WindowEvent arg0) {}
			public void windowIconified(WindowEvent arg0) {}
			public void windowOpened(WindowEvent arg0) {

				List<CaeChatMessage> msgs = logic.getLastMessages();
				for (CaeChatMessage message : msgs) {
					printMessage(message);
				}

				CaeImage.setIcon(iconTray, CaeImage.DEFAULT);
				dialog.requestFocusInWindow();
				inputText.requestFocus();

			}

		});

		logic.addObserver(this);

		panel = new JPanel();
		getContentPane().add(panel);
		panel.setLayout( new GridBagLayout() );
		GridBagConstraints destConst = new GridBagConstraints();
		destConst.insets = new Insets(2,2,2,2);
		destConst.fill = GridBagConstraints.BOTH;
		destConst.weightx = 100;
		destConst.weighty = 100;
		destConst.gridwidth = 2;

		//big TODO
		try {
			textPane = new JTextPane();
		} catch (NullPointerException e1) {
			textPane = new JTextPane();
		}
		JScrollPane paneScrollPane = new JScrollPane(textPane);
		paneScrollPane.setPreferredSize(new Dimension(500, 300));
		paneScrollPane.setMinimumSize(new Dimension(10, 10));
		doc = textPane.getStyledDocument();
		CaeEmoticonsManager.getInstance().addStylesToDocument(doc);
		textPane.setEditable(false);
		//textArea.setLineWrap(true); // TODO

		destConst.gridx = 0;
		destConst.gridy = 0;
		destConst.gridwidth = 2;
		panel.add(paneScrollPane, destConst);

		inputText.addKeyListener(new KeyListener()
		{
			public void keyPressed(KeyEvent e) {
			}
			public void keyReleased(KeyEvent e) {
				if (e.getKeyCode() == 10)
				{
					sendAndClean();
				}
			}
			public void keyTyped(KeyEvent e) {
			}

		});
		destConst.gridx = 0;
		destConst.gridy = 1;
		destConst.weighty = 0;
		destConst.gridwidth = 2;
		panel.add(inputText, destConst);

		JButton sendB = new JButton("Enviar...");
		sendB.addActionListener(this);
		destConst.gridx = 0;
		destConst.gridy = 2;
		destConst.gridwidth = 1;
		panel.add(sendB, destConst);

		CaeEmoticonDefinition smile = CaeEmoticonsManager.getInstance().getEmoticon(":)");
		Image iconImage = CaeEmoticonsManager.getInstance().getEmoticonImage(smile);
		ImageWrapperResizableIcon icon = ImageWrapperResizableIcon.getIcon(iconImage, new Dimension(16, 16));
		JCommandButton emoticonButton = new JCommandButton("Format", icon);
		emoticonButton.setPopupCallback(new PopupPanelCallback()
		{
			public JPopupPanel getPopupPanel(JCommandButton p) {
				JCommandPopupMenu popupMenu = new JCommandPopupMenu(new QuickStylesPanel(), 10, 5);
				return popupMenu;
			}
		});
		emoticonButton.setCommandButtonKind(JCommandButton.CommandButtonKind.POPUP_ONLY);
		emoticonButton.setDisplayState(CommandButtonDisplayState.SMALL);

		destConst.gridx = 1;
		destConst.gridy = 2;
		destConst.gridwidth = 1;
		panel.add(emoticonButton, destConst);

		pack();

		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		setLocation(screenSize.width / 4, screenSize.height /4);

		setResizable(true);
	}

	public void actionPerformed(ActionEvent e)
	{
		sendAndClean();
	}

	String sentText;
	public void sendAndClean()
	{
		sentText = inputText.getText();
		new Thread(new Runnable()
		{
			public void run() 
			{
				if(!sentText.isEmpty())
					CaeChatManager.sendMessage(sentText);
			}
		}).start();
		inputText.setText("");
	}


	public void update(Observable o, Object arg) {

		CaeChatMessage msg = (CaeChatMessage)arg; 

		printMessage(msg);
	}

	/*public void printMessage(CaeChatMessage msg)
	{
		CaeDestination fromDest = CaeDestinatiosManager.getInstance().getDestination(msg.getFrom());

		if(fromDest != null)
			textArea.append(fromDest.getAlias() + ": " + msg.getText()+"\n");
		else
			textArea.append(msg.getFrom() + ": " + msg.getText()+"\n");

		textArea.setCaretPosition(textArea.getDocument().getLength());
	}*/

	private void printMessage(CaeChatMessage msg)
	{

		CaeDestination fromDest = CaeDestinatiosManager.getInstance().getDestination(msg.getFrom());
		try {

			if(fromDest != null)
				doc.insertString(doc.getLength(), fromDest.getAlias()+ ": ", doc.getStyle("bold"));
			else
				doc.insertString(doc.getLength(), msg.getFrom()+ ": ", doc.getStyle("bold"));


			CaeEmoticonsManager emoManager = CaeEmoticonsManager.getInstance();
			String[] msgTexts = emoManager.splitText( msg.getText() ); 

			for (String text : msgTexts) {
				doc.insertString(doc.getLength(), text, getStyle(text));
			}
			doc.insertString(doc.getLength(), "\n", getStyle("regular"));

		} catch (BadLocationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		textPane.setCaretPosition(textPane.getDocument().getLength());
	}

	private AttributeSet getStyle(String styleDef)
	{
		AttributeSet set = doc.getStyle(styleDef);
		if(set == null)
		{
			set = doc.getStyle("regular");
		}
		return set;
	}

	/*public static void main(String[] args) throws TrayIconException, InterruptedException { // TODO a test

		CaeChatManager m = new CaeChatManager();
		new Thread(m).start();

		WindowsTrayIcon.initTrayIcon("pepe");
		String iconPath = CaeClipConfiguration.getInstance().getSProp(CaeClipConfiguration.ICON_FILE);
		Image defaultIcon = Toolkit.getDefaultToolkit().getImage(iconPath);
		WindowsTrayIcon icon = new WindowsTrayIcon(defaultIcon,16,16);

		CaeChatDialog c= new CaeChatDialog(null, m, icon);
		c.setVisible(true);
	}*/


	private class QuickStylesPanel extends JCommandButtonPanel
	{
		private static final long serialVersionUID = 1L;

		public QuickStylesPanel()
		{
			super(32);

			String iconGroupName = "Emoticons";
			addButtonGroup(iconGroupName, 0);

			List<CaeEmoticonDefinition> emoticonsList = CaeEmoticonsManager.getInstance().getEmoticons();
			for (final CaeEmoticonDefinition emoticon : emoticonsList)
			{
				Image iconImage = CaeEmoticonsManager.getInstance().getEmoticonImage(emoticon);
				ImageWrapperResizableIcon icon = ImageWrapperResizableIcon.getIcon(iconImage, new Dimension(16, 16));
				JCommandButton emoticonButton = new JCommandButton(null, icon);
				
		        RichTooltip actionRichTooltip = new RichTooltip();
		        actionRichTooltip.setTitle(emoticon.getName());
		        actionRichTooltip.addDescriptionSection(emoticon.getKeySets()[0]); // TODO
		        emoticonButton.setCommandButtonKind(JCommandButton.CommandButtonKind.ACTION_ONLY);
				emoticonButton.setActionRichTooltip(actionRichTooltip);
				emoticonButton.addActionListener(new ActionListener()
				{
					public void actionPerformed(ActionEvent arg0) {
						Document docu = inputText.getDocument();
						try {
							docu.insertString(inputText.getCaretPosition(), emoticon.getKeySets()[0]+" ", null);
							inputText.requestFocus();
						} catch (BadLocationException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				});
				Dimension d = new Dimension(30, 30);
				emoticonButton.setMinimumSize(d);
				emoticonButton.setMaximumSize(d);
				emoticonButton.setPreferredSize(d);
				addButtonToLastGroup(emoticonButton);
			}

			setSingleSelectionMode(true);
		}
	}
}

